iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 21 篇

Day 21|應用程式該放 EC2、容器還是 Lambda?

  • 分享至 

  • xImage
  •  

上一篇決定了資料適合放在 RDS、Aurora 還是 DynamoDB,接下來來決定應用程式要怎麼執行與部署。

在 AWS 上,常見的選擇包括:

  • EC2:直接在虛擬主機上安裝並執行應用程式。
  • Container(容器):把應用程式與相依套件封裝成映像檔,再交給容器平台執行。
  • Lambda:由請求或事件觸發函式,執行環境主要由 AWS 管理。

選擇時可以先問兩件事:應用程式需要怎麼執行?團隊希望自己管理到哪一層?

例如程式是否需要長時間常駐、是否需要控制作業系統、能不能接受事件驅動的執行方式,以及團隊願意承擔多少維運工作,都會影響最後的選擇。

不過,EC2、容器與 Lambda 並不是完全互斥的三個選項,容器可以跑在 EC2 上,也可以透過 Fargate 執行;Lambda 也支援以容器映像檔作為部署套件。

因此這篇真正要比較的不只是「程式放在哪裡」,而是 應用程式的執行方式、部署單位,以及底層基礎設施由誰負責管理。


先釐清:EC2、容器與 Lambda 並不是完全互斥

Amazon EC2 提供虛擬主機,團隊可以選擇作業系統、安裝套件,並自行管理主機上的應用程式與執行環境。

Container(容器) 是封裝與執行應用程式的方式,程式與相依套件被打包成 Container Image(容器映像檔),再由容器執行環境啟動,容器可以跑在 EC2 上,也可以透過 AWS Fargate 執行,將底層主機管理交給 AWS。

AWS Lambda 則由請求或事件觸發函式執行,AWS 會負責配置與管理執行環境,Lambda 也支援使用符合規範的容器映像檔部署。

這篇比較的是以下三種部署模式:

比較項目 EC2 上直接執行程式 透過容器平台部署 Lambda
部署單位 程式、套件、主機設定 容器映像檔與執行設定 ZIP 套件或容器映像檔
執行方式 常駐服務或批次工作 常駐服務或一次性任務 由請求或事件觸發
擴展方式 增加或調整 EC2 增加容器副本或 Task 依並行需求自動擴展
作業系統管理 團隊負責 依 EC2 / Fargate 而異 AWS 負責
適合需求 需要完整主機控制 希望標準化部署與擴展 事件驅動、短時間執行

EC2:哪些需求值得保留主機控制權?

EC2 適合需要較高主機控制權的情境。

使用 EC2 時,團隊可以選擇作業系統與 Instance Type,配置儲存與網路,並自行安裝需要的 Runtime、套件與其他軟體,因此如果應用程式本身需要碰到底層主機,EC2 通常會是比較直接的選擇。

以下需求可優先評估 EC2:

  • 必須調整作業系統或安裝主機層級的驅動。
  • 軟體需要特定主機權限,無法在受限的執行環境中運作。
  • 既有系統短期內不能容器化或改寫。
  • 團隊已有成熟的主機映像檔、部署與維護流程。

但主機控制權也代表更多管理責任,作業系統更新、套件漏洞、磁碟空間、程式健康狀態與容量,都需要團隊處理。

例如流量增加時,可以透過 Auto Scaling 增加 EC2;但新主機仍然必須完成初始化、取得設定並通過健康檢查,才能接手服務。

如果這些步驟仍需要工程師登入後手動操作,即使設定了 Auto Scaling,也很難可靠地擴展。

因此選擇 EC2 後,應確保環境能透過 AMI、啟動腳本或其他自動化流程重新建立,需要管理主機,不等於需要手動管理每台主機。


容器:把應用程式變成標準化的部署單位

如果團隊希望把應用程式與相依套件整理成固定的部署單位,而不是依賴每台主機上的環境設定,就可以評估容器。

例如一個 API 需要:

內容 範例
語言執行環境 Python
應用程式框架 FastAPI
相依套件 資料庫驅動、影像處理套件
程式碼 API 與商業邏輯

這些內容可以一起封裝成 Container Image(容器映像檔),讓開發、測試與正式環境部署相同的建置產物,資料庫位置、環境參數與機密則由外部設定提供。

這樣一來,應用程式的交付單位就變成一份可以重複部署的映像檔。

更新版本時,只需要建立新的 Image,再由平台逐步替換舊容器,這能降低逐台登入修改檔案造成的環境差異,也讓版本更新與回復都有明確的部署產物。

EC2 也能透過 AMI 與自動化達成環境一致性;容器的差異在於,它把應用程式本身與相依套件整理成較獨立的部署單位,不需要和整台主機綁在一起。

容器打包好之後,誰負責執行?

容器化之後,還要再決定兩件事:

  • 誰管理容器? 例如啟動、重新排程、維持副本數與部署版本,這是 ECS、EKS 等容器編排平台處理的範圍。
  • 容器跑在哪裡? 可以跑在自行管理的 EC2,也可以使用 AWS Fargate,將底層主機管理交給 AWS。

如果容器跑在自行管理的 EC2 上,團隊仍然需要維護主機與容量;使用 Fargate 可以減少這部分工作,但映像檔、資源配置、網路與應用程式本身仍然需要管理。

例如映像檔內的套件出現漏洞,團隊仍然要更新套件、重新建置並部署新的 Image,平台不會自動替換打包進去的內容。

容器也不會自動解決高可用與資料保存,重要資料應放在外部儲存,健康檢查、擴展規則與部署策略也需要另外設定,單純執行一次 docker run 還不等於完整的正式環境部署。

因此,對已經可以容器化的 API、Worker 或批次工作,如果希望統一部署產物、方便擴展與版本更新,可以優先評估 ECS、EKS 等容器平台,再依主機管理需求選擇 EC2 或 Fargate。


Lambda:適合事件驅動、具有明確起點與終點的工作

假設網站新增一個功能:使用者把圖片上傳到 S3 後,自動產生縮圖。

這個工作不需要自行維持一個全天候等待圖片的程序,可以讓 S3 上傳事件觸發 Lambda,由函式讀取圖片、產生縮圖,再把結果寫回 S3。

其他常見的觸發方式包括:

觸發來源 執行工作
S3 物件建立事件 產生縮圖、檢查檔案
API Gateway 收到請求 執行 API 邏輯
EventBridge Scheduler 排程 定期整理資料
SQS 訊息 處理佇列中的工作

Lambda 會使用可用的執行環境處理請求,需要更多容量時再建立新的環境,並不是每次呼叫都重新建立。

應用程式也不能假設下一次一定會使用相同的執行環境,必要的狀態應保存在資料庫或其他外部服務,本機暫存只能作為可以重新建立的資料。

流量增加時,Lambda 怎麼擴展?

Concurrency(並行數) 指同一時間正在執行的請求數量。

Lambda 會依同時執行的請求增加執行環境,因此不需要事先維持固定數量的主機,不過擴展仍受到並行配額、函式設定與服務擴展速度等限制。

對流量不固定、事件數量變化明顯,或不希望自行維持常駐運算容量的工作,Lambda 可以減少主機與容量管理。

但擴展後的壓力仍可能往下游傳遞,例如同時執行的函式增加,資料庫可能突然收到更多連線與查詢,Lambda 能擴展,不代表資料庫與外部 API 也能承受相同流量。


選擇 Lambda 前,要確認哪些限制?

本文以一般 Lambda 函式為主要比較範圍,先確認三件事。

第一,單次工作能不能在時間限制內完成。

一般 Lambda 函式的 Timeout 上限是 900 秒,也就是 15 分鐘,如果不可拆分的工作需要 20~40 分鐘,就不適合直接放進這個執行模式。

也不能只看平均時間,大檔案、外部服務延遲與資料量增加,都可能讓工作超時,測試時應涵蓋合理範圍內最大的輸入。

Lambda Managed Instances 的部分非同步與 Event Source Mapping 呼叫有不同的執行時間限制,不列入本文主要比較範圍。

第二,延遲要求能不能接受初始化時間。

Lambda 建立新的執行環境時,需要初始化執行環境與程式,這就是 Cold Start(冷啟動)。

如果 API 對回應時間很敏感,需要測試初始化與擴展時的延遲,必要時評估 Provisioned Concurrency 等預先準備執行環境的方式,並將額外成本納入考量。

第三,重複執行與下游壓力要怎麼處理。

依事件來源與呼叫方式不同,工作可能被重試或重複投遞,程式需要具備 Idempotency(冪等性),讓同一筆工作重複處理時,不會造成重複扣款或建立重複資料。

並行數也應配合下游容量設定,必要時搭配佇列緩衝,避免大量 Lambda 同時執行時直接壓垮資料庫或外部服務。

Lambda 減少了主機維護,但事件處理、錯誤恢復與相依服務容量,仍然需要設計。

因此,以下需求可以優先評估 Lambda:

  • 工作由 API、訊息、排程或其他事件觸發。
  • 每次執行都有明確的開始與結束。
  • 不需要長時間維持固定的執行環境。
  • 流量變化明顯,希望減少常駐容量管理。

如果應用程式需要長時間持續運行、依賴固定主機狀態,或單次工作超過一般 Lambda 的執行限制,EC2 或容器平台通常會更適合。


同一套系統,可以替不同工作做不同選擇

以下用一個假設情境比較。

一個網站目前有三種工作:

  • 已經容器化、需要全天候服務的 HTTP API。
  • 每次執行約 20~40 分鐘,而且目前無法拆分的資料處理工作。
  • S3 圖片上傳後,以幾秒鐘產生縮圖的功能。

團隊不需要修改主機核心或安裝特殊驅動,也希望減少作業系統維護。

在這些條件下,可以做以下選擇:

工作 優先選擇 判斷原因 需要承擔的管理責任
常駐 HTTP API 容器平台 已有映像檔與既有執行方式,適合持續運行 映像檔更新、健康檢查、擴展與連線管理
20~40 分鐘資料處理 容器平台 超過一般 Lambda 單次執行上限,可在需要時啟動容器,完成後停止 工作觸發、狀態紀錄、重試與中斷處理
圖片縮圖 Lambda 事件觸發、執行時間短,而且不依賴固定本機狀態 事件過濾、冪等性、錯誤處理與並行限制

這個案例沒有優先選擇直接在 EC2 上執行應用程式,因為目前沒有需要自行管理主機的明確理由。

前兩項雖然都使用容器平台,但執行方式不同:HTTP API 需要持續運行,資料處理工作則可以在需要時啟動,完成後停止,至於在 ECS 或 EKS 中要如何實作這兩種執行方式,下一篇會再進一步說明。

另外,選擇容器後,還需要決定底層運算容量由誰管理。

如果團隊已經有成熟的 EC2 維運、自動擴展與成本最佳化流程,或需要較高的主機控制權,可以讓容器執行在 EC2 上。

如果希望減少作業系統與底層主機管理,而且工作負載符合 Fargate 的支援範圍,則可以評估 Fargate。

因此,選擇容器平台 和 決定容器底層使用 EC2 或 Fargate,是兩個不同層次的決策。

HTTP API 仍然可以改成 Lambda,但既然已經有可用的映像檔與部署流程,就需要確認改寫後是否能帶來足夠收益。

20~40 分鐘的資料處理工作則因為超過一般 Lambda 函式的執行時間上限,所以優先排除一般 Lambda 執行模式。

在「API 與長時間工作已經容器化、沒有主機層級需求,而且希望降低作業系統維護負擔」的條件下,可以讓這兩類工作交給容器平台執行,再把短時間的圖片事件交給 Lambda。

這代表團隊需要同時維護容器部署與事件驅動兩種執行流程,但不需要為了統一技術選型,強迫所有工作都使用相同的運算方式。

如果後續出現需要特殊驅動、主機權限或其他底層控制的元件,再針對該元件評估 EC2,不必把整套系統一起改成主機部署。

成本也應依不同工作型態分別估算,零星事件未必值得維持常駐容量;長時間、高使用率的服務,則需要比較 EC2、Fargate 與 Lambda 在實際使用量下的成本差異,並納入 Load Balancer、日誌、網路、儲存與預留容量等相關項目。

因此,EC2、容器與 Lambda 並不是整套系統只能三選一,而是應依不同工作負載的執行方式、管理責任與限制分別選擇。


下一篇

如果決定使用容器,下一步還要回答兩個問題:

  • 誰負責管理容器?
  • 容器實際跑在哪裡?

這就會帶到 ECS、EKS、EC2 與 Fargate 之間的關係。

下一篇會進一步區分容器編排平台與執行容量,並說明 ECS 中持續運行的服務與一次性工作有什麼差異,再比較什麼情況需要 Kubernetes,以及什麼情況下 ECS 搭配 Fargate 就能滿足需求。

參考資料


上一篇
Day 20|資料庫該選 RDS、Aurora,還是 DynamoDB?
下一篇
Day 22|容器上 AWS:ECS、EKS 與 Fargate 怎麼選?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言